<?php

/**
 * 拼多多SAAS关务 统一下单接口（专用）
 * @author chenshubo
 */
namespace App\Service\VendorClient\ShopGwApi;
use App\Service\Code\Normal;
use App\Service\BaseService;
use Service\AppService\IdService;
use App\Service\TaskServer\TaskWorker;

class ShopPddUserGwApiClient extends BaseService
{
    protected $clientConfig;
    /**
     * 初始化配置
     * @param array $apiBody
     */
    public function __construct($apiBody=[])
    {
        $this->clientConfig = $apiBody;
    }
    
    /**
     * 创建订单
     * @param array $params
     * @return mixed
     */
    public function createOrder( $param = [] )
    {
        $supplierGoods  = $param['supplierGoodsInfo'];
        //下单信息
        $orderInfo      = $param['order'];
        //原始商品数据组
        $goodsList      = $supplierGoods['goodsList'];
        //下单商品
        $orderGoods     = $param['order']['goods'];
        
        //处理收获地址问题
        $receiveAddress = implode("", [
            $orderInfo['province'],
            " ",
            $orderInfo['city'],
            " ",
            $orderInfo['district'],
            "n",
            $orderInfo['receiveAddress'],
        ]);

        //获取下单商品信息
        $palceOrderGoods = [];
        $totalGoodsMoney = $freight = 0;
        foreach ($orderGoods as $item )
        {
            //商品价格 = 商品价格 + 商品税费
            $goodsMoney     = bcadd((string)$item['goodsPrice'], (string)($item['goodsTax']??0),2);
            //供应商商品信息
            $supplierGoods  = $goodsList[$item['goodsSku']];
            //上游SKU
            $commoditySKU   = $supplierGoods['supplierSKUCode'];
            //下单数量
            $goodsSaleCount = bcmul((string)$item['goodsNum'],(string)$item['goodsSpecNum']);
            //规格数量
            $goodsSpecNum   = $item['goodsSpecNum'];
            //单个商品价格
            $singlePrice    = bcdiv((string)$goodsMoney,(string)$goodsSpecNum,2);
            //开始进行订单申报商品
            $palceOrderGoods[] = [
                'batchID'               => (string)($supplierGoods['batchID']??''),
                'commodityCount'        => (string)$goodsSaleCount,
                'commoditySKU'          => $commoditySKU,
                'commodityRealPrice'    => (float)$singlePrice,
            ];
            $totalGoodsMoney += (float)(bcmul((string)$goodsSaleCount, (string)$singlePrice,2));
            $freight += (float) $item['freight'];
        }
        
        //总运费(运费 +运费税)
        $delivery       = bcadd((string)$freight, 0.00,2);
        //下单总金额(商品总金额 + 总运费)
        $totalMoney     = bcadd((string)$totalGoodsMoney,(string)$delivery,2);

        //是否支付单申报
        $isDeclarePay   = (
            (isset($orderInfo['isPayDeclare']) && $orderInfo['isPayDeclare'] == 1) ||
            (isset($orderInfo['order_type']) && $orderInfo['order_type'] == 1)
            ) ? true : false ;

        //是否订单申报
        $isOrderDeclare = (isset($orderInfo['isOrderDeclare']) && $orderInfo['isOrderDeclare'] == 1) ? true : false ;
        //拼多多京东扩展参数
        $extends_orderType  = $orderInfo['extends']['orderType'] ?? '';
        $extends_mall_id    = $orderInfo['extends']['mall_id'] ?? '';
        $extends_remark     = $orderInfo['orderRemarks'] ?? '';
        //优惠金额
        $discountMoney      = $orderInfo['discountMoney']??0.00;
        $discountMoney      = $discountMoney >= 0 ? $discountMoney : ( 0 - $discountMoney);
        
        //是否保税自提订单
        $is_bbc_self_take = $param['binfo']['is_bbc_self_take'] ?? 0;
        
        //组装推送上游数据
        $requestParam = [
            'method'    => 'createOrder',
            'data'      => [
                'placeOrderInfo' => [
                    'SingleChannel'         => $orderInfo['orderSource'],
                    'customerCode'          => $supplierGoods['warehouseAccount'],  //货主编号
                    'CompanyOrderCode'      => $orderInfo['supplier_dsn'],      //S2B 子单号
                    'ShopOrderCode'         => $orderInfo['orderSn'],          // 下游订单号
                    'receiverName'          => $orderInfo['receiveName'],
                    'receiverPhone'         => $orderInfo['recveivePhone'],
                    'province'              => $orderInfo['province'],
                    'city'                  => $orderInfo['city'],
                    'district'              => $orderInfo['district'],
                    'ReceiverAddress'       => $orderInfo['receiveAddress'],
                    'paymentName'           => $orderInfo['buyerRealName'],
                    'paymentPhone'          => $orderInfo['buyerPhone'],
                    'paymentCart'           => $orderInfo['buyerIdCard'],
                    'payment'               => $isDeclarePay ? 99 : 1 ,
                    'isDeclarePay'          => $isDeclarePay , //支付单是否已申报（true -已申报，false-未申报）
                    'isOrderDeclare'        => $isOrderDeclare,//订单是否已申报（true -已申报，false-未申报）
                    'totalPrice'            => (float)$totalMoney,
                    'freight'               => (float)$delivery,
                    'DiscountPrice'         => (float)$discountMoney,
                    'palceOrderCommoditys'  => $palceOrderGoods,
                    'payerFlowNo'           => '',
                    'PayCommanyName'        => '',
                    'PayCommanyCode'        => '',
                    'deliveryUrl'           => config('api.yc_sys.deliveryUrl'),
                    'cancelUrl'             => config('api.yc_sys.cancelUrl'),
                    'orderType'             => $is_bbc_self_take == 1 ? 8 : 0,
                ],
                'extendedParameters' => [
                    'orderType' => (string)$extends_orderType,
                    'shop'      => (string)$extends_mall_id,
                    'remark'    => (string)$extends_remark,
                ]
            ],
        ];
        return $this->execute($requestParam);
    }

    /**
     * 取消订单
     * @param array $params
     * @return mixed
     */
    public function cancelOrder( $params = [] )
    {
        $orderSupplier = $params['supplierOrder'];
        $order         = $params['order'];
        $requestParam = [
            'method'    => 'cancelOrder',
            'data'      => [
                'placeOrderConfirmInfo' => [
                    'CompanyOrderCode'  => $orderSupplier['supplier_dsn'],
                    'isConfirm'         => false,
                    'payerFlowNo'       => '',
                    'payCommanyName'    => '',
                    'payCommanyCode'    => '',
                ]
            ],
        ];
        return $this->execute($requestParam);
    }
    
    /**
     * 订单支付
     * @param array $params
     * @return mixed
     */
    public function payOrder( $params = [] )
    {
        $orderSupplier      = $params['supplierOrder'];
        $order              = $params['order'];
        $supplier_dsn       = $orderSupplier['supplier_dsn'];
        $apply_extends      = @json_decode($orderSupplier['apply_extends'],true);
        $apply_extends      = empty($apply_extends) ? $order : $apply_extends;
        $innerTransactionId = $order['inner_transaction_id']??'';
        $innerTransactionId = $innerTransactionId ? $innerTransactionId : ($apply_extends['innerTransactionId']??'');
        $innerTransactionId = $innerTransactionId ? $innerTransactionId : $supplier_dsn;
        $print_data_code    = $apply_extends['waybill_info']['print_data_code'] ?? 0;
        $print_data_msg     = $apply_extends['waybill_info']['print_data_msg'] ?? '';
        $waybill_code       = $apply_extends['waybill_info']['waybill_code']??'';
        $print_data         = $apply_extends['waybill_info']['print_data']??'';
        $requestParam = [
            'method'    => 'payOrder',
            'data'      => [
                'placeOrderConfirmInfo' => [
                    'CompanyOrderCode'  => $orderSupplier['supplier_dsn'],
                    'isConfirm'         => true,
                    'payerFlowNo'       => (string)$order['paySerial'],
                    'payCommanyName'    => $order['payCommanyName'],
                    'payCommanyCode'    => $order['payCommanyCode'],
                    'EnterpriseCode'    => $order['enterpriseNum'],
                    'EBPName'           => $order['enterpriseName'],
                    'DeclareOrderSn'    => $innerTransactionId,
                    'LogisticsCode'     => $waybill_code,//物流单号
                    'DataInfo'          => $print_data,//拼多多面单信息,
                    'printDataCode'     => $print_data_code == Normal::SUC ? true :false,//面单获取成功/失败 code 成功为200，失败为0
                    'printDataMsg'      => $print_data_msg,//面单获取成功/失败 信息
                ]
            ],
        ];
        return $this->execute($requestParam);
    }

    /**
     * 获取订单清关申报报文
     * @param array $param
     */
    public function queryOrderDeclare( $param = [] )
    {
        $supplierOrder      = $param['supplierOrder'];
        $supplier           = $param['supplier'];
        $order_sn           = $supplierOrder['order_sn']; 
        $requestParam = [
            'method'        => 'queryOrderDeclare',
            'return'        => true,
            'uid'           => $order_sn,
            'company_code'  => $supplier['company_code'],
            'method'        => 'queryOrderDeclare',
            'data'          => [
                'companyOrderCode'  => $order_sn
            ],
        ];
        return $this->execute($requestParam);
    }
    
    /**
     * 获取订单申报报文
     * @param array $param
     * @return mixed|unknown[]|string[]|array[]
     */
    public function queryDeclareOrderContentsByOrderSns( array $param = [] , string $method='queryOrderDeclare')
    {
        $supplierOrderList  = $param['supplierOrderList'];
        $supplier           = $param['supplier'];
        $order_sns          = array_column($supplierOrderList,'order_sn');
        $requestParam = [
            'method'        => $method,
            'return'        => true,
            'uid'           => IdService::instance()->getOtherID(),
            'company_code'  => $supplier['company_code'],
            'data'          => $order_sns,
        ];
        return $this->execute($requestParam);
    }

    /**
     * 申报结果通知
     * @param array $param
     * @return mixed|unknown[]|string[]|array[]
     */
    public function ReceiveDeclareResult( array $param = [] )
    {
        $supplierOrderList  = $param['resultOrderList'];
        $supplier           = $param['supplier'];
        $requestParam = [
            'method'        => 'ReceiveDeclareResult',
            'return'        => true,
            'uid'           => IdService::instance()->getOtherID(),
            'company_code'  => $supplier['company_code'],
            'data'          => $supplierOrderList,
        ];
        return $this->execute($requestParam);
    }
    
    /**
     * CURL请求
     * @param $params
     * @return mixed
     */
    public function execute( $param = [] )
    {
        $return        = $param['return'] ?? false;
        $uid           = $param['uid'] ?? false;
        $company_code  = $param['company_code'] ?? false;
        $method        = $param['method'];
        $data          = $param['data'];
        $header = [
            "Content-Type: application/json",
            "Accept:application/json"
        ];

        if( empty($this->clientConfig['baseurl']) ) {
            return Normal::returnCode(Normal::FAIL,"当前仓库参数baseurl未配置");
        }
        
        if( empty($this->clientConfig[$method]) ) {
            return Normal::returnCode(Normal::FAIL,"当前仓库参数【{$method}】未配置");
        }
        
        $baseUrl  = $this->clientConfig['baseurl'];
        $applyUrl = $this->clientConfig['baseurl'].$this->clientConfig[$method];
        
        if( empty($param['data']) ) {
            return Normal::returnCode(Normal::FAIL,"数据不能为空");
        }
        
        if( $param['method'] != 'createOrder' )
        {
            $form_data = [
                'tag'           => 'shopcustom_'.$method,
                'uid'           => $uid ? $uid : IdService::instance()->getOtherID(),
                'company_code'  => $company_code,
                'url'           => $applyUrl,
                'data'          => $data,
                'method'        => 'post',
                'format'        => 'json',
                'header'        => [],
            ];
            
            if( $return ) {
                return Normal::returnCode(Normal::SUC,"获取成功",$form_data);
            }
            
            $parameter = [$form_data];
            $resTask = TaskWorker::instance()->addTask($parameter);
            $resTask = current($resTask);
            $result  = @json_decode($resTask['response']['result'],true);
            if( $resTask['response']['httpCode'] == Normal::SUC ) {
                return Normal::returnCode(Normal::SUC,"OK");
            } else {
                $msg = !empty($result) ? ($result['message']??'请求失败') : $resTask['response']['result'] ;
                return Normal::returnCode(Normal::FAIL,$msg);
            }
        }

        return Normal::returnCode(Normal::SUC,"获取成功",[
            'url'       => $applyUrl,
            'data'      => $data,
            'format'    => 'json'
        ]);
    }
}